<?php
// +-------------------------------------------------------------------
// | 
// +-------------------------------------------------------------------
// | Copyright (c) 2009-2016 All rights reserved.
// +-------------------------------------------------------------------

// 更新数据加密秘钥
// + 更新 config 表中加密配置
// + 重置后台开发者账号密码为 kc123456
error_reporting(0);
PHP_SAPI == 'cli' or exit('use cli');
chdir(__DIR__ . "/../..");

function query ($sqlOrConfig)
{
    static $resConfig;
    if (is_array($sqlOrConfig))
    {
        $resConfig = $sqlOrConfig;
        $link = mysql_connect($resConfig['DB_HOST'] . ':' . $resConfig['DB_PORT'], $resConfig['DB_USER'], $resConfig['DB_PWD'], true) or exit('Can not connect to db host');
        mysql_query("use " . $resConfig['DB_NAME']) or exit('Can not use db');
        mysql_query('set names utf8');
        return true;
    }
    
    $sql = @str_replace('@p_', $resConfig['DB_PREFIX'], $sqlOrConfig);
    $res = mysql_query($sql);
    if (is_bool($res))
    {
        return $res;
    }
    
    $arr = array();
    while ($row = mysql_fetch_array($res, MYSQL_ASSOC))
    {
        $arr[] = $row;
    }
    return $arr;
}

function think_encrypt ($data, $key = '', $expire = 0)
{
    $key = md5($key);
    $data = base64_encode($data);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';
    
    for ($i = 0; $i < $len; $i ++)
    {
        if ($x == $l)
            $x = 0;
        $char .= substr($key, $x, 1);
        $x ++;
    }
    
    $str = sprintf('%010d', $expire ? $expire + time() : 0);
    
    for ($i = 0; $i < $len; $i ++)
    {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    return str_replace(array(
            '+',
            '/',
            '='
    ), array(
            '-',
            '_',
            ''
    ), base64_encode($str));
}

function think_decrypt ($data, $key = '')
{
    $key = md5($key);
    $data = str_replace(array(
            '-',
            '_'
    ), array(
            '+',
            '/'
    ), $data);
    $mod4 = strlen($data) % 4;
    if ($mod4)
    {
        $data .= substr('====', $mod4);
    }
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);
    
    if ($expire > 0 && $expire < time())
    {
        return '';
    }
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';
    
    for ($i = 0; $i < $len; $i ++)
    {
        if ($x == $l)
            $x = 0;
        $char .= substr($key, $x, 1);
        $x ++;
    }
    
    for ($i = 0; $i < $len; $i ++)
    {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1)))
        {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        }
        else
        {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

function kcone_think_encrypt ($data, $key = '', $expire = 0)
{
    if ($data == '')
    {
        return $data;
    }
    return 'kcone_encrypt_' . think_encrypt($data, $key, $expire);
}

function kcone_think_decrypt ($data, $key = '')
{
    if (is_string($data) && strpos($data, 'kcone_encrypt_') === 0)
    {
        $data = think_decrypt(substr($data, 14), $key);
    }
    return $data;
}

$config = require 'config.php';
file_exists('../config.php') and $config = array_merge($config, require '../config.php');
file_exists('../config.dev.php') and $config = array_merge($config, require '../config.dev.php');
file_exists('../config.product.php') and $config = array_merge($config, require '../config.product.php');

query($config);

$key = 'e' . md5(uniqid());
echo "New encrypt key : $key\n";

// 检查配置表
$configRes = query("SELECT * FROM @p_config") ?  : [];
foreach ($configRes as $k => $v)
{
    if ($v['value'] !== '')
    {
        $configVal = kcone_think_decrypt($v['value'], $config['DATA_ENCRYPT_KEY']);
        if ($configVal === false)
        {
            exit("Config data decrypt faild : {$v['name']}\n");
        }
        $v['value'] = $v['group'] == 'model' ? $configVal : kcone_think_encrypt($configVal, $key);
        
        $configRes[$k] = $v;
    }
    else
    {
        unset($configRes[$k]);
    }
}
echo "Check config data : done\n";

// 使用新的密钥加密配置表
foreach ($configRes as $v)
{
    $status = query("UPDATE @p_config SET `value`='" . addslashes($v['value']) . "' WHERE `id`='{$v['id']}'");
    if (! $status)
    {
        exit("Update config data faild : " . mysql_error() . "\n");
    }
}
echo "Update config data : done\n";

if (file_exists('../config.php'))
{
    $configStr = preg_replace("/('|\")DATA_ENCRYPT_KEY\\1\s* =>\s*('|\")(.*)\\2/", "\\1DATA_ENCRYPT_KEY\\1 => \\1{$key}\\1", file_get_contents('../config.php'));
    file_put_contents('../config.php', $configStr);
}
echo "Update config file : done\n";

// 重置 admin 密码
$password = md5(sha1('kc123456') . $key);
$status = query("UPDATE @p_ucenter_member SET `password`='$password' WHERE `id`=1");
if (! $status)
{
    exit("Reset kcadmin password faild :  " . mysql_error() . "\n");
}
echo "Reset kcadmin password : done\n";

